/*
  base2 - copyright 2007-2009, Dean Edwards
  http://code.google.com/p/base2/
  http://www.opensource.org/licenses/mit-license.php

  Contributors:
    Doeke Zanstra
*/

// timestamp: Wed, 30 Sep 2009 07:58:49

new function(_no_shrink_) { ///////////////  BEGIN: CLOSURE  ///////////////

// =========================================================================
// html5/package.js
// =========================================================================

base2.global.html5 = new base2.Package(this, {
  name:    "html5",
  version: "0.5.1",
  imports: "Function2,Enumerable,dom,jsb",
  
  NOT_SUPPORTED: function() {
    throw "Not supported in html5-now.js.";
  },

  get: function(element, propertyName) {
    return this.getBehavior(element).get(element, propertyName);
  },

  set: function(element, propertyName, value) {
    this.getBehavior(element).set(element, propertyName, value);
  },

  getBehavior: function(element) {
    return this[element.nodeName.toLowerCase()] || behavior;
  }
});

eval(this.imports);

// =========================================================================
// html5/header.js
// =========================================================================

var _SUPPORTS_BORDER_BOX = detect("QuirksMode") || (7 != document.documentMode && detect("(style.boxSizing)"));
    
var _HOST          = jsb.host,
    _IMAGES_URL    = _HOST + "images/",
    _OPEN_IMAGE    = _IMAGES_URL + "arrow-up.png",
    _CLOSED_IMAGE  = _IMAGES_URL + "arrow-down.png";

var _PERCENT       = "[%\u066a\ufe6a\uff05\u2030\u2031]",
    _PARSE_RATIO   = new RegExp("([\\d.]+" + _PERCENT + "?)|([\\d.]+).+([\\d.]+)", "g");
    _PERCENT       = new RegExp(_PERCENT);
    
// Indexes to values returned by getRatio().
var _VALUE = 0, _MAX = 1;

var _styleSheet = {
  "source,command,[hidden],[repeat=template]": {
    display: "none!"
  }
};

var _rules = {};

// =========================================================================
// dimensions.js
// =========================================================================

// This is because IE8 is incredibly slow to calculate clientWidth/Height.

// http://stackoverflow.com/questions/800693/clientwidth-performance-in-ie8

// The fix is pretty horrible.
// I use an HTC file (dimensions.htc) that grabs the clientWidth and
// clientHeight properties and caches them.

var _WIDTH = "clientWidth",
    _HEIGHT = "clientHeight";

if (8 == document.documentMode) {

  jsb.clientWidth2 = {};
  Object.defineProperty(global.Element.prototype, "clientWidth2", {
    get: function() {
      return jsb.clientWidth2[this.uniqueID] || this.clientWidth;
    }
  });

  jsb.clientHeight2 = {};
  Object.defineProperty(global.Element.prototype, "clientHeight2", {
    get: function() {
      return jsb.clientHeight2[this.uniqueID] || this.clientHeight;
    }
  });

  _WIDTH = "clientWidth2";
  _HEIGHT = "clientHeight2";
  
  //document.write('<script src="' + jsb.host + 'dimensions.htc"></script>');
}

// =========================================================================
// html5/register.js
// =========================================================================

function _registerElement(tagName, definition) {
  var element = document.createElement(tagName);
  if (definition) {
    if (typeof definition == "string") {
      definition = {display: definition};
    } else {
      definition = extend({}, definition);
    }
    if (element[definition.detect] === undefined) {
      var style = definition.style,
          behavior = definition.behavior;
      if (definition.display) {
        if (!style) style = {};
        style.display = definition.display;
        if (style.display.indexOf("block") == 0 && !style.margin) {
          style.margin = "1em 0"; // default margin for block elements
        }
      }
      if (style) {
        if (_styleSheet[tagName]) {
          extend(_styleSheet[tagName], style);
        } else {
          _styleSheet[tagName] = style;
        }
      }
      if (definition.extraStyles) {
        extend(_styleSheet, definition.extraStyles);
      }
      if (behavior) {
        if (typeof behavior == "string") {
          behavior = _HOST + behavior;
        } else {
          if (!jsb.behavior.ancestorOf(behavior)) {
            behavior = jsb.behavior.extend(behavior);
          }
          html5[tagName] = behavior;
        }
        _rules[tagName] = behavior;
      }
      if (definition.extraRules) {
        extend(_rules, definition.extraRules);
      }
    } else {
      var placeholder = html5[tagName] = jsb.behavior.extend();
      if (definition.methods) forEach.csv (definition.methods, function(name) {
        placeholder[name] = function(element) {
          return element[name].apply(element, Array2.slice(arguments, 1));
        };
      });
    }
  }
};

// =========================================================================
// chrome/theme.js
// =========================================================================

jsb.theme = new Base({
  detect: K("default"),

  "@Windows": {
    defaultTheme: "classic",

    "@NT5\\.1": { // XP
      defaultTheme: "luna/blue"
    },

    "@NT[6-9]": { // Vista
      defaultTheme: "aero"
    },

    detect: function() {
      var colors = _getColors();
      return _WIN_DETECT_COLLISION[colors.join("")] || _WIN_DETECT_ACTIVECAPTION[colors[0]] || _WIN_DETECT_GRAYTEXT[colors[1]] || this.defaultTheme;
    },

    "@NT(6\\.1|[7-9])": { // Windows 7
      detect: K("aero/7")
    },

    "@Chrome|Arora": {
      detect: function() {
        var theme = this.base();
        return !theme || theme == "classic" ? this.defaultTheme : theme;
      }
    }
  },
  
  "@Linux": {
    detect: function() {
      return _LINUX_DETECT_ACTIVECAPTION[_getColors()[0]];
    }
  },

  "@Webkit([1-4]|5[01]|52[^89])|Camino|Mac": {
    detect: K("aqua"),

    "@(Chrome|Arora).+win": {
      detect: K("luna/blue")
    }
  }
});

var _WIN_DETECT_ACTIVECAPTION = {
  "#0054e3": "luna/blue",
  "#8ba169": "luna/olive",
  "#c0c0c0": "luna/silver",
  "#335ea8": "royale",
  "#5e81bc": "royale",
  "#99b4d1": "aero",
  "#c4cbde": "aero",
  "#343434": "zune"
}, _WIN_DETECT_GRAYTEXT = {
  "#808080": "classic",
  "#8d8961": "classic/brick",
  "#a28d68": "classic/desert",
  "#588078": "classic/eggplant",
  "#5a4eb1": "classic/lilac",
  "#489088": "classic/marine",
  "#c6a646": "classic/maple",
  "#786058": "classic/plum",
  "#d7a52f": "classic/pumpkin",
  "#4f657d": "classic/rainyday",
  "#9f6070": "classic/rose",
  "#558097": "classic/slate",
  "#559764": "classic/spruce",
  "#bcbc41": "classic/wheat"
}, _WIN_DETECT_COLLISION = {
  "#0a246a#808080": "classic/standard",
  "#0000ff#00ff00": "classic/contrast/high1",
  "#00ffff#00ff00": "classic/contrast/high2",
  "#800080#00ff00": "classic/contrast/black",
  "#000000#00ff00": "classic/contrast/white"
}, _LINUX_DETECT_ACTIVECAPTION = {
  "#c4c6c0": "clearlooks",
  "#eae8e3": "clearlooks",
  "#dfe4e8": "clearlooks",
  "#eaeaea": "clearlooks",
  "#edeceb": "clearlooks",
  "#efebe7": "human"
};

var rgba = rgb;

jsb.theme.toString = K(jsb.theme.detect() || "default");

base2.userAgent += ";theme=" + jsb.theme;

function rgb(r, g, b) {
  function toHex(value) {
    return (value < 16 ? "0" : "") + value.toString(16);
  };
  return "#" + toHex(r) + toHex(g) + toHex(b);
};

function _getColors() {
  var element = document.createElement("input"),
      style = element.style,
      body = document.body || behavior.querySelector("head");
  var getColor = function(color) {
        style.color = color;
        if (color.toLowerCase() == style.color.toLowerCase()) {
          color = ViewCSS.getComputedPropertyValue(document.defaultView, element, "color");
        } else {
          color = style.color;
        }
        if (/rgb/.test(color)) color = eval(color);
        return color;
      };
  body.appendChild(element);
  // detect OS theme by inspecting the ActiveCaption colour
  var colors = [getColor("ActiveCaption"), getColor("GrayText")];
  body.removeChild(element);
  return colors;
};

// =========================================================================
// chrome/colors.js
// =========================================================================

var _WINDOW =         "window",
    _HIGHLIGHT =      "highlight",
    _HIGHLIGHT_TEXT = "highlighttext";

if (detect("(Webkit([1-4]|5[01]|52[^89])|theme=aqua).+win")) { // webkit pre 528 uses the same colours, no matter the theme
    _WINDOW =         "#ffffff";
    _HIGHLIGHT =      "#427cd9";
    _HIGHLIGHT_TEXT = "#ffffff";
}

// =========================================================================
// chrome/styleSheet.js
// =========================================================================

var _borderColor = {
  "aero":        "#abadb3 #dbdfe6 #e3e9ef #e2e3ea",
  "luna/blue":   "#7f9db9",
  "luna/olive":  "#a4b97f",
  "luna/silver": "#a5acb2",
  "royale":      "#a7a6aa",
  "zune":        "#969696"
}[jsb.theme] || "threedface";

jsb.theme.cssText = jsb.createStyleSheet({
  "*": {
    backgroundPosition:        "9999px 9999px",
    backgroundAttachment:      "scroll!",
    backgroundRepeat:          "no-repeat!",

    "@!theme=classic": {
      padding:                 "2px",
      border:                  "1px solid",
      borderColor:             _borderColor
    },

    "@theme=aqua": {
      padding:                 "1px 2px 2px 2px",
      borderWidth:             "2px 1px 1px 1px",
      borderColor:             "#9e9e9e #b4b4b4 #dadada #b4b4b4"
    }
  },

  ".jsb-dropdown,.jsb-combobox,.jsb-colorpicker,.jsb-datepicker,.jsb-weekpicker": {
    "@theme=aqua": {
      width:                  "10em",
      borderRadius:           "5px",
      boxShadow:              "0 1px 4px rgba(160, 160, 160, 0.5)",

      "@(style.borderImage)": {
        borderImage:          "url(%theme%/dropdown.png) 1 18 1 4!",
        borderStyle:          "none!",
        borderWidth:          "1px 18px 1px 4px!",
        padding:              "1px"
      },

      "@!(style.borderImage)": {
        backgroundImage:      "url(%theme%/bg-dropdown.png)!",
        backgroundPosition:   "right center!",
        padding:              "1px 22px 1px 4px!",
        border:               "1px solid #545454!"
      }
    },

    "@!theme=aqua": {
      paddingRight:           "19px!",
      backgroundImage:        "url(%theme%/dropdown.png)!"
    }
  },

  ".jsb-colorpicker,.jsb-datepicker,.jsb-weekpicker": {
    width:                    "8em"
  },

  ".jsb-progressbar,.jsb-slider,.jsb-colorpicker": {
    cursor:                   "default",
    textIndent:               "-10em!", // hide text for purely visual controls (Gecko, Webkit and Opera)
    userModify:               "read-only!",
    MozUserSelect:            "none!", // still buggy in webkit

    "@MSIE": { // hide text for purely visual controls (MSIE)
      textIndent:             0,

      "@MSIE(5.5|6|7)": {
        lineHeight:           999
      },

      "@MSIE[^567]": {
        lineHeight:           999,
        verticalAlign:        "middle" // Argh! This is bad. It means that the normal vertical alignment doesn't work. :(
      }
    }
  },

  ".jsb-progressbar,.jsb-slider": {
    verticalAlign:         "middle" // not sure about this
  },

  ".jsb-progressbar": {
    minHeight:             "8px",
    borderColor:           "threeddarkshadow",
    borderWidth:           "1px",
    borderRadius:          "5px",
    backgroundImage:       "url(%theme%/progressbar.png)!",

    "@Opera8": {
      backgroundImage:     "url(themes/s/progressbar.png)!"
    }
  },

  ".jsb-slider": {
    height:               "21px",
    minHeight:            "21px",
    padding:              0,
    border:               "none",
    backgroundColor:      "transparent",
    backgroundImage:      "url(%theme%/slider.png)!",

    "@Opera8": {
      backgroundImage:    "url(themes/s/slider.png)!"
    },

    "@Gecko1\\.[0-3]": {
      backgroundColor:    "#f2f2f2"
    }
  },

  ".jsb-popup": {
    visibility:         "hidden",
    backgroundColor:    _WINDOW,
    borderWidth:        "1px!",
    position:           "absolute!",
    zIndex:             "999999!",
    cursor:             "default",
    padding:            "0!",
    margin:             "0!",

    "@Gecko|Opera|theme=aqua|Webkit": {
      borderColor:      "threedshadow!",
      borderStyle:      "outset!",

      "@Opera": {
        borderStyle:    "solid!"
      }
    },

    "@theme=classic": {
      borderColor:      "threedshadow!",
      borderStyle:      "solid!"
    }
  },

  ".jsb-spinner": {
    "@!Opera[78]": {
      textAlign:        "right"
    },
    width:              "5em",
    paddingRight:       "19px!",
    backgroundImage:    "url(%theme%/spinner.png)!"
  },

  ".jsb-timepicker,.jsb-monthpicker": {
    width:              "8ex",
    paddingRight:       "19px!",
    backgroundImage:    "url(%theme%/spinner.png)!",

    "@QuirksMode|Gecko1\\.[0-3]|Opera8": {
      width:            "6em"
    }
  },

  ".jsb-popup .jsb-datepicker-days": {
    userSelect:         "none!",
    width:              "100%!",
    margin:             "2px 0 0 0!",
    padding:            "2px!",
    backgroundColor:    _WINDOW + "!",
    color:              "windowtext!"
  }
});

jsb.theme.cssText += "\n" + jsb.createStyleSheet({
  ".jsb-popup *": {
    margin: "0!",
    padding: "0!"
  },
  
  ".jsb-popup option": {
    padding: "0 3px!"
  },

  ".jsb-colorpicker": {
    width:         "4em",

    "@QuirksMode|Gecko1\\.[0-3]|Opera8": {
      width:       "6em"
    }
  },

  ".jsb-datepicker": {
    width:         "12ex",

    "@QuirksMode|Gecko1\\.[0-3]|Opera8": {
      width:       "15ex"
    }
  },

  ".jsb-weekpicker": {
    width:         "11ex",

    "@QuirksMode|Gecko1\\.[0-3]|Opera8": {
      width:       "14ex"
    }
  },

  "@Webkit": {
    ".jsb-slider:focus:not(.slider_focus)": {
      outline:        "none!"
    }
  },

  "@!Webkit": {
    ".progressbar_focus,.slider_focus,.colorpicker_focus": {
      outline:        "1px dotted"
    }
  },

  ".jsb-datalist": {
    display:         "none!"
  },

  ".jsb-menulist": {
    "@!MSIE": {
      overflow:      "auto!"
    },

    "@MSIE": {
      overflowY:     "auto!"
    }
  },

  ".jsb-menulist div": {
    margin:          "0!",
    padding:         "1px 2px!",
    overflow:        "hidden!",
    whiteSpace:      "nowrap!"
  },

  ".jsb-colorpicker-popup": {
    backgroundColor:      "buttonface!",
    color:                "buttontext!",
    fontSize:             "11px!",
    padding:              "4px!",
    overflow:             "hidden!",
    whiteSpace:           "nowrap!",
    userSelect:           "none!",

    "@Webkit([1-4]|5[01]|52[^89])|Chrome": {
      backgroundColor: "#ece9d8!"
    }
  },

  ".jsb-colorpicker-popup input": {
    fontSize:        "11px",
    margin:          "4px 2px!",
    verticalAlign:   "middle",
    width:           "127px"
  },

  ".jsb-datepicker-popup": {
    backgroundColor:      "#fcfcfd!",
    overflow:             "hidden!",

    "@theme=classic": {
      backgroundColor:      "threedface!"
    }
  },

  ".jsb-datepicker-popup input": {
    width:             "5ex!",
    marginLeft:        "2px!",
    padding:           "2px 19px 2px 2px!",

    "@QuirksMode|Gecko1\\.[0-3]|Opera8": {
      width:           "9ex!"
    },

    "@!MSIE[567]|Opera": {
      padding:         "1px 19px 1px 2px!"
    }
  },

  ".jsb-datepicker-popup th": {
    backgroundColor: "infobackground!",
    color:           "infotext!",
    fontWeight:      "normal!"
  },

  ".jsb-datepicker-popup th,.jsb-datepicker-days td": {
    padding:         "2px 0!",
    textAlign:       "center!",
    width:           "14%!"
  },

  ".jsb-datepicker-days td.disabled,.jsb-datepicker-days tr.disabled td": {
    color:            "graytext!"
  },

  ".jsb-datepicker-days td.selected,.jsb-datepicker-days tr.selected td": {
    backgroundColor: "inactivecaptiontext!",
    color:           "inactivecaption!",
    opacity:         0.5
  },

  ".jsb-datepicker-days_focus td.selected,.jsb-datepicker-days_focus tr.selected td": {
    backgroundColor: _HIGHLIGHT + "!",
    color:           _HIGHLIGHT_TEXT + "!",
    opacity:         1
  },

  "@theme=luna\\/blue": {
    ".jsb-datepicker-popup th": {
      backgroundColor: "#ffffe1!"
    }
  },

  "@theme=(human|clearlooks)": {
    ".jsb-combobox,.jsb-datepicker,.jsb-weekpicker,.jsb-colorpicker": {
      "borderTopRightRadius":          "5px",
      "borderBottomRightRadius":       "5px"
    }
  },

  "@theme=aqua": {
    ".jsb-menulist": {
      opacity:            0.95
    },

    ".jsb-spinner,.jsb-timepicker,.jsb-monthpicker": {
      borderTopWidth:                  "1px",
      paddingTop:                      "2px",
      borderRightColor:                "transparent",
      borderTopRightRadius:            "5px",
      borderBottomRightRadius:         "5px"
    },

    ".jsb-spinner[disabled],.jsb-spinner[readonly],.jsb-timepicker[disabled],.jsb-timepicker[readonly],.jsb-monthpicker[disabled],.jsb-monthpicker[readonly]": {
      borderColor:      "#d6d6d6 #e0e0e0 #f0f0f0 #e0e0e0"
    },

    ".jsb-combobox[readonly],.jsb-combobox[disabled],.jsb-datepicker[readonly],.jsb-datepicker[disabled],.jsb-weekpicker[readonly],.jsb-weekpicker[disabled]": {
      "@(style.borderImage)": {
        borderImage:   "url(%theme%/dropdown-disabled.png) 1 18 1 4!"
      },

      "@!(style.borderImage)": {
        backgroundImage:   "url(%theme%/bg-dropdown-disabled.png)!"
      }
    },

    "@(style.borderImage)": {
      ".jsb-colorpicker": {
        borderImage:       "url(%theme%/colorpicker.png) 1 18 1 4!"
      },

      ".jsb-colorpicker[readonly],.jsb-colorpicker[disabled]": {
        borderImage:       "url(%theme%/colorpicker-disabled.png) 1 18 1 4!"
      }
    },

    "@!(style.borderImage)": {
      ".jsb-colorpicker": {
        backgroundImage:   "url(%theme%/bg-colorpicker.png)!"
      },

      ".jsb-colorpicker[readonly],.jsb-colorpicker[disabled]": {
        backgroundImage:   "url(%theme%/bg-colorpicker-disabled.png)!"
      }
    },

    ".jsb-combobox[disabled],.jsb-datepicker[disabled],.jsb-weekpicker[disabled],.jsb-colorpicker[disabled],.jsb-progressbar[disabled]": {
      color:         "windowtext",
      opacity:       0.5
    },

    ".jsb-colorpicker-popup,.jsb-datepicker-popup": {
      backgroundColor: _WINDOW + "!",
      backgroundImage: "url(%theme%/metal.png)!",
      backgroundRepeat: "repeat!"
    },

    ".jsb-datepicker": {
      width:         "7em"
    },

    ".jsb-weekpicker": {
      width:         "6em"
    },

    ".jsb-monthpicker": {
      width:         "5em"
    },

    ".jsb-datepicker-popup th": {
      backgroundColor: "#89acd5!",
      color:           "white!"
    }
  },

  ".jsb-tooltip": {
    borderColor:        "graytext!",
    backgroundColor:    "infobackground!",
    color:              "infotext!",
    fontSize:           "small!",
    boxShadow:          "2px 4px 4px rgba(160, 160, 160, 0.5)",

    "@MSIE.+QuirksMode": {
      fontSize:         "x-small!"
    }
  },

  ".jsb-tooltip div": {
    padding:            "2px 3px 0 3px!"
  },

  "@(hasFeature('WebForms','2.0'))": {
    "input[list],input[type=number],input[type=date],input[type=time],input[type=month],input[type=week],input[type=range]": {
      backgroundImage:  "none!"
    }
  },

  ".jsb-error": {
    borderColor:      "#ff5e5e",
    outlineColor:     "#ff5e5e"
  },

  "@Safari.+win" : {
    "@!theme=aqua": {
      "input,select": {
        outlineColor:  _borderColor
      }
    }
  }
});

// =========================================================================
// html5/canvas.js
// =========================================================================

var _CANVAS_JS = "canvas.js";
;;; _CANVAS_JS = "canvas.php";

_registerElement("canvas", {
  detect: "getContext",

  display: "block",

  // if <canvas> is not implemented then we can at least support it for MSIE
  behavior: detect("MSIE") ? _CANVAS_JS + "#html5.canvas" : null,
  
  methods: "getContext"
});

// =========================================================================
// html5/details.js
// =========================================================================

_registerElement("details", {
  detect: "open",

  display: "block",

  // The real display is handled by the layout() method.
  // This speeds things up a little for CSS2 compliant browsers.
  extraStyles: {
    "details dt": { // should be :first-of-type but this targets more browsers
      paddingLeft:            "14px",
      backgroundPosition:     "1px center!",
      backgroundAttachment:   "scroll!",
      backgroundRepeat:       "no-repeat!"
    },

    "details > dt": {
      backgroundImage:        "url(images/arrow-down.png)"
    },

    "details[open] > dt": {
      backgroundImage:        "url(images/arrow-up.png)"
    },
    
    "@!MSIE[5-7]": {
      "details > dd": {
        overflow:               "hidden",
        height:                 0
      },

      "details[open] > dd": {
        height:                 "auto"
      }
    }
  },

  behavior: {
    open: false,

    oncontentready: function(element) {
      // Create a legend if the <dt> element is missing.
      var legend = this.querySelector(element, ">dt");
      if (!legend) {
        legend = document.createElement("dt");
        legend.innerHTML = "Details";
        element.insertBefore(legend, element.firstChild);
      }
      this.layout(element);
    },

    onclick: function(element, event, x) {
      // Toggle open state if the up/down-arrow is clicked.
      var legend = this.querySelector(element, ">dt");
      if (legend && Traversal.includes(legend, event.target) && x <= 14) {
        this.toggle(element, "open");
      }
    },

    onpropertyset: function(element, event, propertyName) {
      // If the "open" property is set then redraw.
      if (propertyName == "open") this.layout(element);
    },

    layout: function(element, state) {
      var open = this.get(element, "open"),
          legend = this.querySelector(element, ">dt"),
          content = this.querySelector(element, ">dd");
      if (legend) {
        this.setStyle(legend, "backgroundImage", "url(" + (open ? _OPEN_IMAGE : _CLOSED_IMAGE) + ")", true); // !important
      }
      if (content) {
        content.style.height = open ? "auto" : "0";
      }
    }
  }
});

// =========================================================================
// html5/ratio.js
// =========================================================================

// An interface shared by meter/progress.
// Parses max/value from textContent if no attributes are specified.

var ratio = behavior.extend({
  // Default DOM property values.
  max:   0,
  value: 0,

  onmouseover: function(element) {
    if (!element.title) {
      this._untitledElement = element;
      element.title = this.get(element, "textContent");
    }
  },

  onmouseout: function(element) {
    if (element == this._untitledElement) {
      delete this._untitledElement;
      element.title = "";
    }
  },

  onpropertyset: function(element, event, propertyName) {
    if (typeof this[propertyName] == "number" || propertyName == "innerHTML" || propertyName == "textContent") {
      this.layout(element);
    }
  },

  getRatio: function(element) {
    var max = this.getAttribute(element, "max"),
        value = this.getAttribute(element, "value");
    if (value == null) {
      var parsed = this.parseTextContent(element);
      if (max == null) {
        if (typeof parsed == "number") {
          value = parsed;
          max = 1;
        } else if (typeof parsed == "object") {
          value = parsed[_VALUE];
          max = parsed[_MAX];
        } else {
          value  = 0;
        }
      } else if (typeof parsed == "number") {
        value = parsed;
      } else {
        value = 0;
      }
    }
    if (isNaN(max) || max == null || max == "") {
      max = 1;
    }
    return [value - 0 || 0, max - 0];
  },

  parseTextContent: function(element) {
    var parsed = match(this.get(element, "textContent"), _PARSE_RATIO);
    if (parsed[1]) {
      var max = Math.max(parsed[0], parsed[1]),
          value = Math.min(parsed[0], parsed[1]);
    } else if (_PERCENT.test(parsed = parsed[0])) {
      max = parsed.indexOf("\u2031") > 0 ? 10000 : parsed.indexOf("\u2030") > 0 ? 1000 : 100,
      value = Number(parsed.slice(0, -1));
    } else {
      return isNaN(parsed) ? "" : Number(parsed);
    }
    if (!isNaN(max) && !isNaN(value)) {
      return [value, max];
    }
    return "";
  }
});

// =========================================================================
// html5/meter.js
// =========================================================================

_registerElement("meter", {
  detect: "max",

  display: "inline-block",

  "@Gecko": {
    display: "-moz-inline-box;display:inline-block"
  },

  style: {
    verticalAlign: "-0.2em",
    backgroundColor: "inactivecaption",
    width: "5em",
    height: "1em",
    boxSizing: "border-box",
    textIndent: "-100%"
  },

  behavior: ratio.extend({
    min: 0,

    onattach: function(element) {
      this.layout(element);
    },

    layout: function(element) {
      var min = this.get(element, "min") || 0,
          values = this.getRatio(element),
          max = values[_MAX],
          value = values[_VALUE];
      value = value < min ? min : value > max ? max : (value - 0) || 0;
      var width = element[_WIDTH],
          height = element[_HEIGHT],
          isVertical = height > width,
          length = isVertical ? height : width,
          relativeValue =  (value - min) / (max - min),
          border = ~~(relativeValue * length) + "px solid",
          style = element.style;
      style.borderLeft = isVertical ? "" : border;
      style.borderBottom = isVertical ? border : "";
      if (!_SUPPORTS_BORDER_BOX) {
        var fixed = ~~(length - (relativeValue * length)) + "px";
        style.width = isVertical ? "" : fixed;
        style.height = isVertical ? fixed : "";
      }
    }
  })
});

// =========================================================================
// html5/progress.js
// =========================================================================

_registerElement("progress", {
  detect: "max",

  display: "inline-block",
  
  "@Gecko": {
    display: "-moz-inline-box;display:inline-block"
  },

  style: {
    backgroundImage:      "url(%theme%/progressbar.png)!",
    backgroundPosition:   "9999px 9999px",
    backgroundAttachment: "scroll!",
    backgroundRepeat:     "no-repeat!",
    verticalAlign:        "-0.2em",
    width:                "10em",
    height:               "1em",
    boxSizing:            "border-box",
    textIndent:           "-100%",
    border:               "1px solid threeddarkshadow",
    borderRadius:         "5px",

    "@Opera8": {
      backgroundImage:    "url(themes/s/progressbar.png)!"
    }
  },

  behavior: ratio.extend({
    _CHUNK_SIZE: 1,    // some progress bars are shown in chunks
    _IMAGE_SIZE: 3000, // the actual size of the background image
    
    "@theme=luna": {
      _CHUNK_SIZE: 10  // luna themes use chunked progress bars
    },
    
    "@Opera8": {
      _IMAGE_SIZE: 2000
    },
    
    onattach: function(element) {
      if (element[_HEIGHT] > element[_WIDTH]) {
        this.setOrientation(element, "vertical");
      }
      this.layout(element);
    },

    layout: function(element) {
      var values = this.getRatio(element),
          relativeValue = values[_VALUE] / values[_MAX],
          clientWidth = element[_WIDTH],
          clientHeight = element[_HEIGHT];

      if (clientHeight > clientWidth) {
        var left = (-clientWidth / 2) * (clientWidth + 3) - 2,
            top = ~~(clientHeight * relativeValue);
        top = clientHeight - Math.round(top / this._CHUNK_SIZE) * this._CHUNK_SIZE;
      } else {
        left = ~~(clientWidth * relativeValue) - this._IMAGE_SIZE;
        left = Math.round(left / this._CHUNK_SIZE) * this._CHUNK_SIZE;
        top = (-clientHeight / 2) * (clientHeight + 3) - 2;
      }

      element.style.backgroundPosition = ~~left + "px " + ~~top + "px";
    },

    setOrientation: function(element, orientation) {
      if (orientation == "vertical") {
        var backgroundImage = this.getComputedStyle(element, "backgroundImage");
        this.setStyle(element, "backgroundImage", backgroundImage.replace(/\.png/i, "-vertical.png"), true);
      } else if (element.style.backgroundImage) {
        element.style.backgroundImage = "";
      }
    }
  })
});

// =========================================================================
// html5/time.js
// =========================================================================

_registerElement("time", {
  detect:  "dateTime",

  display: "inline",
  
  behavior: {
    dateTime: "",
    pubDate: false,
    
    onattach: function(element) {
      this.layout(element);
    },

    get: function(element, propertyName) {
      if (propertyName == "valueAsDate") {
        var dateTime = this.hasAttribute(element, "datetime") ?
          this.parseDateFromAttribute(element) :
          this.parseDateFromText(element);
        return isNaN(dateTime) ? null : new Date(dateTime);
      }
      return this.base(element, propertyName);
    },

    parseDateFromAttribute: function(element) {
      var dateTime = this.get(element, "dateTime");
      if (dateTime) {
        if (dateTime.indexOf("T") == -1) dateTime += "T";
        return Date2.parse(dateTime);
      }
      return NaN;
    },

    parseDateFromText: function(element) {
      var textContent = trim(this.get(element, "textContent")),
          dateTime = Date2.parse(textContent);
      if (!isNaN(dateTime)) return dateTime;
      dateTime = Date2.parse(textContent + "T");
      if (!isNaN(dateTime)) return dateTime;
      dateTime = Date2.parse("T" + textContent);
      return dateTime;
    },

    layout: function(element) {
      if (!this.get(element, "textContent")) {
        var dateTime = this.parseDateFromAttribute(element);
        if (!isNaN(dateTime)) {
          dateTime = new Date(dateTime);
          var showTime = this.get(element, "dateTime").indexOf("T") != -1;
          if (Date.prototype.toLocaleString) {
            var textContent = showTime ? dateTime.toLocaleString() : dateTime.toLocaleDateString();
          } else {
            textContent = showTime ? dateTime : dateTime.toDateString();
          }
          this.set(element, "textContent", textContent);
        }
      }
    }
  }
});

// =========================================================================
// html5/media.js
// =========================================================================

var _MEDIA_JS = "media.js";
;;; _MEDIA_JS = "media.php";

var _MEDIA_METHODS = "canPlayType,load,play,pause";

_registerElement("audio", {
  detect: "play",
  
  display: "none",
  
  extraStyles: {
    "audio[controls]": {
      display: "inline"
    }
  },
  
  methods: _MEDIA_METHODS,

  behavior: _MEDIA_JS + "#html5.audio"
});

_registerElement("video", {
  detect:  "play",

  display: "block",
  
  style: {
    width: "300px",
    height: "150px"
  },

  methods: _MEDIA_METHODS,

  behavior: _MEDIA_JS + "#html5.video"
});

// =========================================================================
// html5/forms.js
// =========================================================================

/* Web Forms 2.0 */

var _WF2_METHODS = "checkValidity,setCustomValidity";

var _FORMS_JS = _HOST + "forms.js",
    _RM_JS = _HOST + "rm.js";

;;; _FORMS_JS = _HOST + "forms.php";
;;; _RM_JS = _HOST + "rm.php";

var _input = document.createElement("input");

try {
  _input.type = "color";
} catch (x) {}
if (_input.type != "color") {
  _rules["input[type=color]"] = _FORMS_JS + "#chrome.colorpicker";
}

var _cssText = jsb.theme.cssText;

forEach ({
  form: "checkValidity,dispatchFormChange,dispatchFormInput",
  input: _WF2_METHODS + ",stepUp,stepDown",
  output: _WF2_METHODS,
  select: _WF2_METHODS,
  textarea: _WF2_METHODS
}, function(methods, tagName) {
  _registerElement(tagName, {detect: "checkValidity", methods: methods});
});

_registerElement("datalist", {
  detect:  "options",
  display: "none"
});

if (!detect("(hasFeature('WebForms','2.0'))")) {
  extend(_rules, {
    "form": _FORMS_JS + "#html5.form",
    "button,input,textarea,select": _FORMS_JS + "#chrome",
    "input[type=number]": _FORMS_JS + "#chrome.spinner",
    "input[type=range]": _FORMS_JS + "#chrome.slider",
    "input[type=date]": _FORMS_JS + "#chrome.datepicker",
    "input[type=month]": _FORMS_JS + "#chrome.monthpicker",
    "input[type=week]": _FORMS_JS + "#chrome.weekpicker",
    "input[type=time]": _FORMS_JS + "#chrome.timepicker",
    "input[list]": _FORMS_JS + "#chrome.combobox",
    "button[type=add],button.html5-add": _RM_JS + "#jsb.rm.add",
    "button[type=remove],button.html5-remove": _RM_JS + "#jsb.rm.remove",
    "button[type=move-up],button.html5-move-up": _RM_JS + "#jsb.rm.moveup",
    "button[type=move-down],button.html5-move-down": _RM_JS + "#jsb.rm.movedown"
  });
  if (_input.autofocus === undefined) {
    _rules["button[autofocus],input[autofocus],textarea[autofocus],select[autofocus]"] = {
      onattach: function(element) {
        try {
          //if (this._element && this.compareDocumentPosition()) { //-@DRE
            element.focus();
            if (element.select) element.select();
          //  this._element = element;
          //}
        } catch (x) {
          // the control is probably hidden
        }
      }
    };
  }
  _styleSheet[".html5-template"] = {display:"none!"};
  _cssText = new RegGrp({
    "\\*?\\.jsb\\-combobox": "input[list]",
    "\\*?\\.jsb\\-spinner": "input[type=number]",
    "\\*?\\.jsb\\-(\\w+)picker([^-])": "input[type=$1]$2",
    "\\*?\\.jsb\\-slider": "input[type=range]",
    "\\*?\\.jsb\\-error": "input.jsb-error"
  }).exec(_cssText);
}

if (jsb.clientWidth2) {
  _cssText += "\ninput[type=number],input[type=range],input[type=date],"+
    "input[type=month],input[type=week],input[type=time],"+
    "input[type=color],input[list],progress,meter{behavior:url(dimensions.htc)}";
}

jsb.createStyleSheet(_cssText);

// =========================================================================
// html5/init.js
// =========================================================================

_registerElement("abbr");

forEach.csv("article,section", partial(_registerElement, undefined, {
  detect:  "cite",
  display: "block"
}));

forEach.csv("aside,dialog,footer,header,hgroup,nav", partial(_registerElement, undefined, "block"));

_registerElement("figure", {
  display: "block",
  style: {
    margin: "1em 40px"
  }
});

_registerElement("mark", {
  style: {
    background: "yellow"
  }
});

// Create the style sheet.
jsb.createStyleSheet(_styleSheet);

// Cache images.
forEach ([_OPEN_IMAGE, _CLOSED_IMAGE], function(src) {
  (new Image).src = src;
});

// Create the rules.
html5.rules = new jsb.RuleList(_rules);

eval(this.exports);

}; ////////////////////  END: CLOSURE  /////////////////////////////////////
